vue3
<!-- author: xuett -->
<!-- date: 2025-07-07 16:06:18 -->
<!-- description:  -->
<template>
  <div class="chart-box">
    <v-chart :option="chartOption" autoresize />
  </div>
</template>

<script setup>
const state = reactive({
  cardData: [
    { name: "5A景区", value: 9 },
    { name: "4A景区", value: 125 },
    { name: "3A景区", value: 156 },
    { name: "其他", value: 19 }
  ],
  chartOption: {}
});
const { chartOption } = toRefs(state);

onMounted(() => {
  initChart();
});

const initChart = () => {
  let total = 0;
  state.cardData.forEach((item) => {
    total += item.value;
  });
  state.chartOption = {
    color: ["#2968EA", "#BBCEF1", "#CEAA72", "#63C664"],
    title: {
      text: total,
      subtext: "景区(个)",
      padding: 0,
      itemGap: 0,
      textStyle: {
        color: "#fff",
        fontSize: 24
      },
      subtextStyle: {
        fontSize: 14,
        color: "#fff",
        align: "center",
        fontStyle: "italic"
      },
      x: "25%",
      y: "50%"
    },
    grid: {
      bottom: "5%",
      left: "5%",
      right: "5%"
    },
    tooltip: {
      trigger: "item",
      formatter: "{b}<br/> {c}个  ({d}%)",
      backgroundColor: "#255DA9",
      textStyle: {
        color: "#fff"
      }
    },
    legend: {
      width: 240,
      top: "20%",
      right: "5%",
      itemWidth: 7,
      itemHeight: 7,
      itemGap: 18,
      icon: "roundRect",
      formatter: (name) => {
        let target = state.cardData.find((item) => item.name == name);
        var arr = ["{a|" + name + "}", "{b|" + ((target.value / total) * 100).toFixed(2) + "%}", "{c|" + target.value + "个}"];
        return arr.join(" ");
      },
      textStyle: {
        // 添加
        rich: {
          a: {
            color: "#fff",
            fontSize: 12,
            fontWeight: "normal",
            width: 80
          },
          b: {
            fontSize: 14,
            // fontWeight: "normal",
            width: 60,
            color: "#fff",
            align: "right"
          },
          c: {
            fontSize: 12,
            color: "#fff",
            width: 60,
            align: "right"
          }
        }
      },
      data: state.cardData.map((item) => item.name)
    },
    series: [
      // 主要展示层的
      {
        radius: ["45%", "63%"],
        center: ["25%", "50%"],
        type: "pie",
        label: {
          show: false
        },
        data: state.cardData
      },
      // 边框的设置
      {
        radius: ["40%", "45%"],
        center: ["25%", "50%"],
        type: "pie",
        label: {
          show: false
        },
        labelLine: {
          show: false
        },
        animation: false,
        emphasis: {
          scale: false
        }, //鼠标移入变大
        tooltip: {
          show: false
        },
        data: [
          {
            value: 1,
            itemStyle: {
              color: "rgba(100, 139, 166, 0.51)"
            }
          }
        ]
      },
      {
        name: "外边框",
        type: "pie",
        clockwise: false, //顺时加载
        center: ["25%", "50%"],
        radius: ["73%", "73%"],
        label: {
          show: false
        },
        tooltip: {
          show: false
        },
        emphasis: {
          scale: false
        }, //鼠标移入变大
        data: [
          {
            value: 9,
            name: "",
            itemStyle: {
              borderWidth: 2,
              borderColor: "rgba(51, 114, 210, 0.26)"
            }
          }
        ]
      }
    ]
  };
};
</script>

<style scoped lang="scss">
.chart-box {
  width: 100%;
  height: 100%;
  padding: 15px;
  background-color: #000;
}
</style>
